package logic

import (
	"encoding/json"
	"fmt"
	"github.com/go-resty/resty/v2"
	"imagesearch/internal/config"
	"imagesearch/internal/types"
	"path"
)

type Condition struct {
	Feature string `json:"feature"`
	Field   string `json:"field, default=feature1"`
}

type Sum struct {
	Conditions []Condition `json:"sum"`
}

type SearchRequest struct {
	Query         Sum `json:"query"`
	IsBruteSearch int `json:"is_brute_search,default=1"`
}

type ItemData struct {
	ItemName string `json:"name"`
	IMG_URL  string `json:"url"`
}

type HitConent struct {
	Index  string   `json:"_index"`
	Type   string   `json:"_type"`
	Id     string   `json:"_id"`
	Score  float64  `json:"_score"`
	Source ItemData `json:"_source"`
}

type Hits struct {
	Total    int          `json:"total"`
	MaxScore float64      `json:"max_score"`
	Hits     []*HitConent `json:"hits"`
}

type Shards struct {
	Total      int `json:"total"`
	SuccessFul int `json:"successful"`
}

type SearchResult struct {
	Took    int    `json:"took"`
	TimeOut bool   `json:"time_out"`
	Hits    Hits   `json:"hits"`
	Shards  Shards `json:"_shards"`
}

func SearchVearch(config config.VearchConfig, image string) (ret []types.Item) {

	var requestUrl = config.Url + "/" + config.DbName + "/" + config.SpaceName + "/_search"
	client := resty.New()
	result := &SearchResult{}

	req := new(SearchRequest)
	req.IsBruteSearch = 1
	req.Query.Conditions = []Condition{{Feature: path.Join(config.SearchTmpPath, image), Field: "feature1"}}
	requestJson, _ := json.Marshal(req)
	fmt.Println("request URl:", requestUrl)

	res, err := client.R().SetResult(result).SetHeader("Content-type", "application/json").
		ForceContentType("application/json").
		SetBody(req).
		Post(requestUrl)

	resultJson, _ := json.Marshal(result)
	fmt.Println("SearchVearch response:", string(requestJson), string(resultJson), res.String())

	ret = []types.Item{}
	if err != nil {
		fmt.Println("SearchVearch error:", err)
		return ret
	}
	if res.StatusCode() != 200 {
		fmt.Println("SearchVearch server error:", res.String())
		return ret
	}
	if result.Hits.Total == 0 {
		fmt.Println("SearchVearch no hit.")
		return ret
	}
	for _, data := range result.Hits.Hits {
		ret = append(ret, types.Item{Url: data.Source.IMG_URL})
	}
	return ret
}
